package com.oocl.euc.core.maintenance.repository;

import com.oocl.euc.core.builder.FunctionAuthBuilder;
import com.oocl.euc.core.builder.FunctionBuilder;
import com.oocl.euc.core.builder.RoleBuilder;
import com.oocl.euc.core.builder.StatusBuilder;
import com.oocl.euc.core.common.ITTestBase;
import com.oocl.euc.core.maintenance.model.Function;
import com.oocl.euc.core.maintenance.model.FunctionAuth;
import com.oocl.euc.core.maintenance.model.Role;
import com.oocl.euc.core.maintenance.model.Status;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.junit.Assert.assertTrue;


public class FunctionRepositoryIT extends ITTestBase {

    private List<Long> roleIds = new ArrayList<>();

    private Long statusId;

    @Autowired
    private FunctionRepository functionRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private FunctionAuthRepository functionAuthRepository;

    @Autowired
    private StatusRepository statusRepository;

    @Autowired
    private FunctionBuilder functionBuilder;

    @Autowired
    private RoleBuilder roleBuilder;

    @Autowired
    private FunctionAuthBuilder functionAuthBuilder;

    @Autowired
    private StatusBuilder statusBuilder;


    @Before
    public void setUp() throws Exception {
        initDataForTest();
    }

    @After
    public void tearDown() throws Exception {
        removeTEstDataFromDB();
    }

    private void initDataForTest() {

        Role r1 = roleBuilder.defaultBuilder().withRoleName("test role1 name").saveToDB();
        Role r2 = roleBuilder.defaultBuilder().withRoleName("test role2 name").saveToDB();

        roleIds.add(r1.getId());
        roleIds.add(r2.getId());


        Status s1 = statusBuilder.defaultOverallStatusBuilder().saveToDB();
        statusId = s1.getId();


        FunctionAuth functionAuth1 = functionAuthBuilder.defaultBuilder().withRole(r1).create();
        FunctionAuth functionAuth2 = functionAuthBuilder.defaultBuilder().withRole(r2).create();
        FunctionAuth functionAuth3 = functionAuthBuilder.defaultBuilder().withRole(r1).withStatus(s1).create();
        FunctionAuth functionAuth4 = functionAuthBuilder.defaultBuilder().withRole(r2).withStatus(s1).create();


        Set<FunctionAuth> functionAuthSet1 = new HashSet<>();
        functionAuthSet1.add(functionAuth1);
        functionAuthSet1.add(functionAuth2);

        Set<FunctionAuth> functionAuthSet2 = new HashSet<>();
        functionAuthSet2.add(functionAuth3);
        functionAuthSet2.add(functionAuth4);

        Function f1 = functionBuilder.defaultBuilder()
                .withRoleRelated(false)
                .withStatusRelated(false)
                .withFunctionAuth(functionAuthSet1).saveToDB();

        Function f2 = functionBuilder.defaultBuilder()
                .withRoleRelated(false)
                .withStatusRelated(true)
                .withFunctionName("Test function name2")
                .withFunctionDesc("Test function desc2")
                .withFunctionAuth(functionAuthSet2)
                .saveToDB();

    }

    private void removeTEstDataFromDB() {

        functionAuthRepository.deleteAll();
        roleRepository.deleteAll();
        statusRepository.deleteAll();
        functionRepository.deleteAll();

    }


    @Test
    public void should_return_function_list_when_given_role_id_list() {


        List<Function> functions = functionRepository.findFunctionByRoleIds(roleIds);

        assertTrue(functions.size() == 1);
        assertTrue("Test function name".equals(functions.get(0).getFunctionName()));
        assertTrue("Test function desc".equals(functions.get(0).getFunctionDesc()));
        List<FunctionAuth> list = new ArrayList(functions.get(0).getFunctionAuthSet());
        assertTrue("test role1 name".equals(list.get(0).getRole().getRoleName()) || "test role1 name".equals(list.get(1).getRole().getRoleName()));
    }

    @Test
    public void should_return_function_list_when_given_function_status_related_is_zero_and_function_role_related_is_zero() {
        List<Function> functions = functionRepository.findFunctionNotRelatedWithRole();
        assertTrue(functions.size() == 1);
        assertTrue("Test function name".equals(functions.get(0).getFunctionName()));
        assertTrue("Test function desc".equals(functions.get(0).getFunctionDesc()));
        List<FunctionAuth> list = new ArrayList(functions.get(0).getFunctionAuthSet());
        assertTrue("test role1 name".equals(list.get(0).getRole().getRoleName()) || "test role1 name".equals(list.get(1).getRole().getRoleName()));
    }

    @Test
    public void should_return_function_list_when_given_status_id_and_role_id_list() {
        List<Function> functions = functionRepository.findFunctionByRoleIdsAndStatus(statusId, roleIds);
        assertTrue(functions.size() == 1);
        assertTrue("Test function name2".equals(functions.get(0).getFunctionName()));
        assertTrue("Test function desc2".equals(functions.get(0).getFunctionDesc()));
        List<FunctionAuth> list = new ArrayList<>(functions.get(0).getFunctionAuthSet());
        assertTrue("TEST2".equals(list.get(0).getStatus().getStatusName()));
        assertTrue("TEST2".equals(list.get(1).getStatus().getStatusName()));
    }

    @Test
    public void should_return_function_list_when_given_status_id() {
        List<Function> functions = functionRepository.findFunctionByStatus(statusId);
        assertTrue(functions.size() == 1);
        assertTrue("Test function name2".equals(functions.get(0).getFunctionName()));
        assertTrue("Test function desc2".equals(functions.get(0).getFunctionDesc()));
        List<FunctionAuth> list = new ArrayList<>(functions.get(0).getFunctionAuthSet());
        assertTrue("TEST2".equals(list.get(0).getStatus().getStatusName()));
        assertTrue("TEST2".equals(list.get(1).getStatus().getStatusName()));
    }


}